﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using System.Text;
using System.Collections.ObjectModel;

namespace DTC.Database
{
    //В этом классе будет происходит всякая там чушь связанная непосредственно
    //с чтением и записью в базу данных. 
    public class DatabaseInterface
    {
        private DTCDatabase db;
        public DTCDatabase Db
        {
            get
            {
                return db;
            }
        }

        public DatabaseInterface()
        {
            db = new DTCDatabase(DTC.Properties.Settings.Default.DTCDatabaseConnectionString);
        }

        public void ChangeCancel()
        {
            ChangeSet changeSet = App.DBI.Db.GetChangeSet();
            if (changeSet.Deletes.Count != 0)
            {
                IList<object> deletes = changeSet.Deletes;
                foreach (object delete in deletes)
                {
                    Type T = delete.GetType();
                    Db.GetTable(T).InsertOnSubmit(delete);
                }
            }
            if (changeSet.Inserts.Count != 0)
            {
                IList<object> inserts = changeSet.Inserts;
                foreach (object insert in inserts)
                {
                    Type T = insert.GetType();
                    Db.GetTable(T).DeleteOnSubmit(insert);
                }
            }
            if (changeSet.Updates.Count != 0)
            {
                IList<object> updates = changeSet.Updates;
                foreach (object update in updates)
                {
                    Db.Refresh(RefreshMode.OverwriteCurrentValues, update);
                }
            }
        }

        public void ChangeCancel(object update)
        {
            ChangeSet changeSet = App.DBI.Db.GetChangeSet();
            if (changeSet.Deletes.Contains(update))
            {
                Type T = update.GetType();
                Db.GetTable(T).InsertOnSubmit(update);

            }
            if (changeSet.Inserts.Contains(update))
            {
                Type T = update.GetType();
                Db.GetTable(T).DeleteOnSubmit(update);
            }
            if (changeSet.Updates.Contains(update))
            {
                Db.Refresh(RefreshMode.OverwriteCurrentValues, update);
            }
        }

        #region PatientStuff
        public List<DTC.Database.DTCPatient> GetAllPatiens()
        {
            Table<DTCPatient> PatientsTable = db.GetTable<DTCPatient>();

            var q =
                from p in PatientsTable
                select p;
            return q.ToList();
        }
        public List<DTC.Database.DTCDisease>GetAllDiseases()
        {
            var q = 
                from d in db.DTCDiseases
                select d;
            return q.ToList();
        }
        public List<DTC.Database.DTCInsuranceCompany> GetAllInsuranceCompanies()
        {
            var q =
                from ic in db.DTCInsuranceCompanies
                select ic;
            return q.ToList();
        }
        public List<DTC.Database.DTCParent> GetPatientsParents(int pID)
        {
            var q =
                from p in db.DTCParents
                where p.PatientID == pID
                select p;
            return q.ToList();
        }

        public List<DTCPolyclinic> GetAllPolyclinics()
        {
            var q =
                    from p in Db.DTCPolyclinics
                    select p;
            return q.ToList();
        }

        public List<DTCDrugPrescription> GetAllPatientPrescriptions(int PatientID)
        {
            var q =
                 from pr in db.DTCDrugPrescriptions
                 where pr.PatientID == PatientID
                 select pr;
            return q.ToList();
        }
        public List<DTCDrugIssue> GetAllPatienIssues(int PatientID)
        {
            var q =
                    from iss in db.DTCDrugIssues
                    where iss.DTCDrugPrescription.PatientID == PatientID
                    select iss;
            return q.ToList();
        }


        public List<DTCPatientOrder> GetAllPatientPrescriptionOrder(int PrescID)
        {
            var q =
                    from po in db.DTCPatientOrders
                    where po.DrugPrescriptionID == PrescID
                    select po;
            return q.ToList();
        }
        /// <summary>
        /// /////
        /// temp stuff
        /// </summary>
        /// <returns></returns>
        public List<DTCDrug> GetStock()
        {
            /*List<DTCDrug> tmp = new List<DTCDrug>();
            tmp.Add(new DTCDrug() { Name="Fcuck"});
            tmp.Add(new DTCDrug() { Name = "sdfgvcb" });
            tmp.Add(new DTCDrug() {Name = "Ширево" });
            tmp.Add(new DTCDrug() { Name = "Лабла" });
            tmp.Add(new DTCDrug() { Name = "Нахсдйасх" });
            tmp.Add(new DTCDrug() { Name = "Ампицилин" });
            return tmp;*/
            return new List<DTCDrug>();
        }
        /// <summary>
        /// /
        /// </summary>
        /// <returns></returns>

        #endregion
        #region DoctorsStuff
        public List<DTC.Database.DTCDoctor> GetAllDoctors()
        {
            Table<DTCDoctor> DoctorsTable = db.GetTable<DTCDoctor>();

            var q =
                from d in DoctorsTable
                select d;
            return q.ToList();
        }
        public List<DTC.Database.DTCSpecialization> GetAllSpecializations()
        {
            Table<DTCSpecialization> SpecializationsTable = db.GetTable<DTCSpecialization>();

            var q =
                from s in SpecializationsTable
                select s;
            return q.ToList();
        }

        #endregion
        #region AddressStuff
        public List<DTCAddress> GetAllAddresses()
        {
            var q =
                from a in Db.DTCAddresses
                select a;
            return q.ToList();
        }
        public List<DTCArea> GetAllAreas()
        {
            var q = from a in Db.DTCAreas
                    select a;
            return q.ToList();
        }

        public List<DTCRegion> GetAllRegions()
        {
            var q =
                from r in Db.DTCRegions
                select r;
            return q.ToList();
        }
        public List<DTCDistrict> GetAllDistricts()
        {
            var q =
                from d in Db.DTCDistricts
                select d;
            return q.ToList();
        }
        public List<DTCCity> GetAllCities()
        {
            var q =
                from c in Db.DTCCities
                select c;
            return q.ToList();
        }
        public List<DTCStreet> GetAllStreets()
        {
            var q =
                from s in Db.DTCStreets
                select s;
            return q.ToList();
        }
        #endregion
        #region DrugStuff
        public List<DTC.Database.DTCDrug> GetAllDrugs()
        {
            var q =
                from d in db.DTCDrugs
                select d;
            return q.ToList();
        }
        public List<DTCDrugUnit> GetAllDrugUnits()
        {
            var q =
                    from du in db.DTCDrugUnits
                    select du;
            return q.ToList();
        }
        public List<DTCIssueForm> GetAllIssueForms()
        {
            var q =
                    from o in db.DTCIssueForms
                    select o;
            return q.ToList();
        }
        public List<DTCSupplier> GetAllSuppliers()
        {
            var q =
                    from s in db.DTCSuppliers
                    select s;
            return q.ToList();
        }
        public List<DTCManufacturer> GetAllManufacturers()
        {
            var q =
                    from m in db.DTCManufacturers
                    select m;
            return q.ToList();
        }
        public List<DTCManufacturer> GetDrugManufacturers(int DrugID)
        {
            List<DTCManufacturer> result = new List<DTCManufacturer>();
            var q =
                    from m in db.DTCManufacturers
                    select m;
            foreach (DTCManufacturer tmpMan in q)
            {
                foreach (DTCDrug tmpDrug in tmpMan.ManufacturedDrugs)
                {
                    if (tmpDrug.DrugID == DrugID)
                    {
                        result.Add(tmpMan);
                        break;
                    }
                }
            }
            return result;
        }
        public List<DTCBox> GetAllBoxes()
        {
            var q =
                    from b in db.DTCBoxes
                    select b;
            return q.ToList();
        }
        public List<DTCDrugStore> GetStore()
        {
            var q =
                    from s in db.DTCDrugStores
                    select s;
            return q.ToList();
        }
        public List<DTCOrder> GetAllOrders()
        {
            var q =
                    from o in db.DTCOrders
                    select o;
            return q.ToList();
        }
        public List<DTCOrder> GetOrdersByTime(DateTime From, DateTime To)
        {
            var q =
                from o in db.DTCOrders
                where ((o.DateFrom.Value >= From && o.DateFrom.Value <= To)
                        ||
                       (o.DateTo >= From && o.DateTo <= To))
                select o;
            return q.ToList();
        }

        public List<DTCDrugPrescription> GetActivePrescriptions()
        {
            var q =
                    from p in db.DTCDrugPrescriptions
                    where p.Status.Value == true
                    select p;
            return q.ToList();
        }
        public List<DTCDrugPrescription> GetActivePrescriptionsOnTimeInterval(DateTime TimeFrom, DateTime TimeTo)
        {
            var q =
                    from p in db.DTCDrugPrescriptions
                    select p;
            /*
             * where ((p.CourseStartDate.Value >= TimeFrom 
                            && (p.CourseStartDate.Value<=TimeTo))
                            || (p.CourseStartDate.Value.AddDays(p.CourseDurationDays.Value)>=TimeFrom
                            && p.CourseStartDate.Value.AddDays(p.CourseDurationDays.Value)<=TimeTo)
                            &&
                            p.Status.Value == true)
             * 
             * 
             */
            List<DTCDrugPrescription> Dps = new List<DTCDrugPrescription>();
            foreach (DTCDrugPrescription p in q)
            {
                if ((
                    (p.CourseStartDate.Value <= TimeFrom && p.CourseStartDate.Value.AddDays(p.CourseDurationDays.Value) >= TimeFrom)
                        ||
                        (p.CourseStartDate.Value <= TimeTo && p.CourseStartDate.Value.AddDays(p.CourseDurationDays.Value) >= TimeTo) 
                        ||
                        (p.CourseStartDate.Value <= TimeFrom && p.CourseStartDate.Value.AddDays(p.CourseDurationDays.Value) >= TimeTo)
                    )
                        &&
                         p.Status.Value == true)
                    Dps.Add(p);
            }
            return Dps;
        }

        public PatientOrderStatuse GetStatusByID(int ID)
        {
            var q =
                from p in db.PatientOrderStatuses
                where p.StatusID == ID
                select p;
            if (q.Count() >= 0)
                return q.ToList()[0];
            else return null;
        }

        public List<DrugNeeded> CalculateDrugNeed(DateTime From, DateTime To)
        {
            List<DTCDrugPrescription> activePrescriptions = GetActivePrescriptions();
            List<DrugNeeded> TotalNeededDrugs = new List<DrugNeeded>();
            
            List<DrugNeeded> CurrentPrescriptionDrugNeed;
            bool DrugFound=false;
            foreach (DTCDrugPrescription dp in activePrescriptions)
            {
                CurrentPrescriptionDrugNeed = dp.DrugNeed(From, To);
                if (CurrentPrescriptionDrugNeed != null)
                {
                    foreach (DrugNeeded tmp in CurrentPrescriptionDrugNeed)
                    {
                        foreach (DrugNeeded AlreadyAdded in TotalNeededDrugs)
                        {
                            DrugFound = false;
                            if (IsSameDataObject(tmp.Drug,
                                                 AlreadyAdded.Drug))
                            {
                                AlreadyAdded.Count += tmp.Count;
                                DrugFound = true;
                                break;
                            }
                        }
                        if (!DrugFound)
                        {
                            TotalNeededDrugs.Add(tmp);
                        }
                    }
                }
            }
            return TotalNeededDrugs;
        }

        public bool IsSameDataObject(Object a, Object b)
        {
            if (a == null || b == null)
                return false;
            string stra = a.ToString(); 
            string strb = b.ToString();
            if ( stra != strb )
                return false;
            if (a is DTCDrug)
            {
                if ((a as DTCDrug).DrugID == (b as DTCDrug).DrugID)
                    return true;
                else return false;
            }
            if (a is DTCDrugUnit)
            {
                if ((a as DTCDrugUnit).DrugUnitID == (b as DTCDrugUnit).DrugUnitID)
                    return true;
                else return false;
            }
            if (a is DTCBox)
            {
                if ((a as DTCBox).BoxID == (b as DTCBox).BoxID)
                    return true;
                else return false;
            }
            return false;
        }
        public DateTime GetLastOrderDate()
        {
            DateTime? tmp= null;
            DateTime result = DateTime.Today;
            var q =
                    from o in db.DTCOrders
                    select o;
            tmp = q.ToArray().Max(p => p.DateTo);
            if (tmp != null)
                if (tmp.HasValue)
                    result = tmp.Value;
            return result;
        }

        public List<PatientOrderStatuse> GetStatuses()
        {
            var q =
                    from p in db.PatientOrderStatuses
                    select p;
            List<PatientOrderStatuse> mtp = q.ToList();
            return mtp;
        }  

        #endregion
        #region VisitsStuff
        public List<DTCVisit> GetVisitsByDate(DateTime Date)
        {
            var q =
                from v in Db.DTCVisits
                where ((DateTime)v.DateFrom).Date == Date.Date
                select v;
            return q.ToList();
        }
        public List<DTCVisit> GetVisitsByPatient(DTCPatient Patient)
        {
            var q =
                from v in Db.DTCVisits
                where v.PatientID == Patient.PatientID
                select v;
            return q.ToList();
        }
        #endregion
    }
}
